import { useEffect, useState, useImperativeHandle, forwardRef, Ref, useRef } from 'react';
// import { ClockCircleOutlined } from '@ant-design/icons'
import { getMessage, TextWidget } from '@inbiz/react';
import { Timeline } from '@inbiz/antd';
import { inbiz } from '@inbiz/core';
import { useEvents } from '@inbiz/utils';
import { useModelList } from '@inbiz/hooks';
import moment from 'moment';
import './style.less';
import api from './api';

export interface TimeLineProps {
  /**
   * @description 组件样式名，和style样式对应 ↓↓ eg: inbiz-TimeLine ↓↓
   */
  prefixCls?: string;
  /**
   * @description 类型
   * @default primary
   */
  type?: string;
  /**
   * @description 扩展样式名
   * @default button
   */
  className?: string;
  /**
   * @description 标题以及显示状态
   */
  title?: { status?: boolean; value?: string };
  /**
   * @description 文字
   */
  mode?: string;
  mode2?: string;
  /**
   * @description 自定义颜色
   */
  color?: string;
  /**
   * @description 自定义图标
   */
  icon?: string;
  /**
   * @description 显示方式
   * @default crosswise
   */
  arrangement?: string;
  /**
   * @description 数据源
   * @default 1
   */
  sourceModel?: string;
  inbiz: inbiz;
  callBackEvents?: {
    onParamFormate?: <T>(param: T) => T;
    onRequest?: (param: any) => Promise<any>;
    onData?: <T>(data: T) => T;
  };

  emit?: {
    (type: 'onload'): void;
  };
  /**
   * @description 内容是否以卡片的方式显示
   * @default false
   */
  contentCard?: boolean;
  /**
   * @description 降序排序
   * @default false
   */

  reverse?: boolean;
  /**
   * @description 文字在左
   * @default false
   */
  timeLeft?: boolean;
  /**
   * @description 过滤过期时间
   * @default false
   */
  filterExpired?: boolean;
  /**
   * @description 数据
   */
  data?: [
    {
      time: number | string;
      content: string;
      icon?: string;
      color?: string;
      active?: boolean;
    },
  ];
  /**
   * @description 配置数据
   * @default false
   */
  configData: {
    source: number;
    sourceModel: string;
    tableData: [
      {
        time: number | string;
        content: string;
        icon?: string;
        color?: string;
        active?: boolean;
      },
    ];
    formValue: {
      timeKey: string;
      contentKey: { [key: string]: any }[];
      recordNum: string;
    };
  };
  /**
   * @modelname 模型名称
   */
  modelname: string;
}

/**
 * 纵轴-自定义节点
 * @param icon 图标
 * @param color 边框颜色
 * @param timeTemp 时间戳
 * @param filterExpired 过滤过期时间
 * @returns dom
 */
const IconDot = ({
  prefixCls,
  icon = '',
  color = '',
  timeTemp = 0,
  filterExpired = false,
  props,
}) => {
  // 开启时间过滤
  const nowday = new Date().getTime();
  if (filterExpired && nowday > timeTemp) {
    return (
      <div
        className={`inbiz-TimeLine-dot inbiz-TimeLine-dot-disabled`}
        style={{ transform: props.mode === 'right' ? 'translateX(2px)' : '' }}
      ></div>
    );
  }
  return icon ? (
    <i className={`inbiz-TimeLine-custom-dot ${icon}`} />
  ) : (
    <div
      className={`inbiz-TimeLine-dot ${filterExpired ? `inbiz-TimeLine-dotTR` : ''}`}
      style={{ borderColor: color }}
    ></div>
  );
};

/**
 * 横轴组件
 * @param data 数据
 * @param reverse 是否降序排序
 * @param mode 显示方式
 * @param filterExpired 是否过滤过期时间
 * @returns
 */
const CrosswiseLine = ({
  prefixCls,
  data = [],
  reverse = false,
  mode = 'top',
  filterExpired = false,
  props,
}) => {
  let newData = data.map((it: any) => {
    // it.time = moment(it.time).valueOf();
    return it;
  });
  const activedArr = newData.filter((it) => it.active);
  // 选择高亮的时间
  const activedTime = activedArr.map((it) => moment(it.time).valueOf());
  // 当前时间戳
  const nowTimeTemp = new Date().getTime();
  if (reverse) {
    // 时间由远及近排序
    newData.sort((a, b) => {
      const aTime = a.time;
      const bTime = b.time;
      return moment(bTime).valueOf() - moment(aTime).valueOf();
    });
  }

  return (
    <div className={`inbiz-TimeLine-crosswise`}>
      <ul className={`inbiz-TimeLine-crosswise-panel`}>
        {newData &&
          newData.map((item, index) => {
            /**
             * 设置节点状态：过期、完成、激活、未激活（目前只有过期处理）
             * 过期：节点数据时间戳小于现在时间时间戳则过期
             */
            const state = filterExpired
              ? moment(item.time).valueOf() < nowTimeTemp
                ? 'expired'
                : ''
              : !activedTime.length
              ? ''
              : activedTime[0] > moment(item.time).valueOf()
              ? 'complete'
              : activedTime.includes(moment(item.time).valueOf())
              ? 'actived'
              : 'nonactived';
            return (
              <li
                key={moment(item.time).valueOf()}
                style={{
                  flexDirection: mode === 'top' ? 'column-reverse' : 'column',
                }}
              >
                <div className="node">
                  <div className={`dot dot-${state}`}></div>
                  {index !== newData.length - 1 && <div className="line"></div>}
                </div>
                <div className={`inbiz-TimeLine-contain inbiz-TimeLine-contain-${state}`}>
                  <div className={`time`} style={{ lineHeight: 'normal' }}>
                    {typeof item.time === 'number'
                      ? props.configData?.source == 1
                        ? moment(item.time).format(props.configData.selectValue)
                        : moment(item.time).format('YYYY-MM-DD')
                      : item.time}
                  </div>
                  <div
                    className={`content ${newData.length > 1 ? '' : 'content-auto'}`}
                    title={getMessage(item.content)}
                    style={{ lineHeight: 'normal', marginBottom: 10, marginTop: 8 }}
                  >
                    {item.linkAddress ? (
                      <a href={item.linkAddress} target="_blank" style={{ cursor: 'pointer' }}>
                        <TextWidget>{item.content}</TextWidget>
                      </a>
                    ) : (
                      <span>
                        <TextWidget>{item.content}</TextWidget>
                      </span>
                    )}
                  </div>
                </div>
              </li>
            );
          })}
      </ul>
    </div>
  );
};

type IRef = Ref<ReturnType<typeof api>>;

const TimeLine = forwardRef((props: TimeLineProps, ref: IRef) => {
  const mounting = useRef(true);
  const {
    className,
    mode,
    mode2,
    reverse,
    timeLeft,
    filterExpired,
    configData,
    contentCard,
    arrangement,
    emit,
  } = props;
  const prefixCls = 'inbiz-TimeLine';
  const [configEvents] = useEvents(props.callBackEvents, props.emit);
  const { runAsync, error } = useModelList(configEvents);
  const [data, setData] = useState<
    { time: any; id: number; content: string; linkAddress?: string; icon: any }[]
  >([]);
  // let data = []
  // console.log(props);

  /**
   * 加载数据
   * source===1 静态数据：时间数据格式化为时间戳后设置为当先展示数据
   * source===2 动态数据：从接口请求的数据中获取展示数据字段的数据，初始化排序为升序，当记录数操作设置需要展示的数据时进行数据截取
   */
  useEffect(() => {
    if (
      props.sourceModel &&
      props?.inbiz?.appInfo &&
      props.sourceModel === configData.sourceModel
    ) {
      const recordLen =
        configData.formValue && configData.formValue.recordNum
          ? parseInt(configData.formValue.recordNum)
          : 999;
      runAsync({
        appId: props.inbiz.appInfo.appId,
        key: props.sourceModel,
        orderInfo: [
          {
            modelName: props.modelname,
            fieldName: configData.formValue?.timeKey?.split('$')[0] || '',
            sortType: props.reverse ? 'desc' : 'asc',
            order: 0,
          },
        ],
        pageInfo: {
          index: 1,
          size: recordLen,
        },
      }).then((res: { Rows?: Array<any> }) => {
        const resRows = res.Rows || [];
        if (configData.source === 2) {
          emit?.('onload');
          let arr = resRows.map((item, index) => {
            const resetItem: any = { key: index };
            resetItem.time = item[configData.formValue.timeKey?.split('$')[1]];
            let contentValue = configData.formValue.contentKey?.map?.((v, index) => {
              if (
                configData.formValue.contentKey &&
                index < configData.formValue.contentKey.length - 1
              ) {
                let splitJoint = ' ';
                if (v.splitJoint) {
                  splitJoint = v.splitJoint;
                }
                return item[v?.value?.split('$')[1]] + splitJoint;
              } else {
                return item[v?.value?.split('$')[1]];
              }
            });
            resetItem.content = contentValue;
            return resetItem;
          });
          // 初始化排序-默认升序
          arr.sort((a, b) => {
            const aTime = a.time;
            const bTime = b.time;
            return moment(aTime).valueOf() - moment(bTime).valueOf();
          });

          if (arr.length > recordLen) {
            const newArr = reverse
              ? arr.splice(arr.length - recordLen, recordLen)
              : arr.splice(0, recordLen);
            setData(newArr);
            return;
          }
          setData(arr);
        }
      });
    }
    if (props.configData.source === 1) {
      const transferTime = configData.tableData.map((it) => {
        it.time = moment(it.time).valueOf();
        return it;
      });
      emit?.('onload');
      setData(transferTime || []);
    }
  }, [props.sourceModel, props?.inbiz?.appInfo, props.configData]);

  useImperativeHandle(
    ref,
    () => ({
      ...api(configEvents, { setState: setData, data }),
    }),
    [data],
  );

  return (
    <div className={`inbiz-TimeLine`}>
      <div
        className={`inbiz-TimeLine-wrapper`}
        style={{ paddingTop: arrangement === 'crosswise' && mode2 === 'top' ? '0' : '10px' }}
      >
        {arrangement === 'crosswise' ? (
          <CrosswiseLine
            prefixCls={prefixCls}
            reverse={reverse}
            data={data}
            mode={mode2}
            filterExpired={filterExpired}
            props={props}
          />
        ) : (
          <div className={`inbiz-TimeLine-lengthways`}>
            <Timeline mode={mode} reverse={reverse}>
              {data &&
                data.map((item, index) => {
                  return (
                    <Timeline.Item
                      key={index}
                      dot={
                        (item.icon || filterExpired) && (
                          <IconDot
                            prefixCls={prefixCls}
                            icon={item.icon}
                            timeTemp={moment(item.time).valueOf()}
                            filterExpired={filterExpired}
                            props={props}
                          />
                        )
                      }
                    >
                      <div className={`inbiz-TimeLine-contain`}>
                        {!timeLeft && (
                          <div
                            className={`time`}
                            style={{
                              color: 'var(--inbiz-color-text)',
                              fontSize: 'var(--inbiz-font-size-base)',
                            }}
                          >
                            {typeof item.time === 'number'
                              ? props.configData.source == 1
                                ? moment(item.time).format(props.configData.selectValue)
                                : moment(item.time).format('YYYY-MM-DD')
                              : item.time}
                          </div>
                        )}
                        <div
                          className={`content ${contentCard ? 'content-card' : ''}`}
                          style={{
                            color: 'var(--inbiz-color-text)',
                            fontSize: 'var(--inbiz-font-size-base)',
                            margin: '8px 0',
                          }}
                        >
                          {item.linkAddress ? (
                            <a
                              href={item.linkAddress}
                              target="_blank"
                              style={{ cursor: 'pointer' }}
                            >
                              <TextWidget>{item.content}</TextWidget>
                            </a>
                          ) : (
                            <span
                              style={{
                                color: 'var(--inbiz-color-text)',
                                fontSize: 'var(--inbiz-font-size-base)',
                              }}
                            >
                              <TextWidget>{item.content}</TextWidget>
                            </span>
                          )}
                        </div>
                      </div>
                    </Timeline.Item>
                  );
                })}
            </Timeline>
          </div>
        )}
      </div>
    </div>
  );
});

export default TimeLine;
